# 入院记录加密
from faker import Faker
import random
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import hashlib
import base64
from data_mock.utils import FileUtil, MysqlUtils_AI

fake = Faker('zh_CN')


# ====== 加密模拟函数 ======
def mock_encrypt(data):
    """模拟加密过程（实际使用时替换为真实加密算法）"""
    if not data:
        return None
    # 模拟步骤：UTF-8编码 -> SHA256哈希 -> Base64编码
    return base64.b64encode(
        hashlib.sha256(data.encode('utf-8')).digest()
    ).decode('utf-8')[:100]  # 截断适应字段长度


# ====== 基础数据配置 ======
CANCER_DIAGNOSES = [
    ("C34.901", "肺恶性肿瘤", "T2N1M0"),
    ("C50.902", "乳腺恶性肿瘤", "T1N0M0"),
    ("C16.901", "胃恶性肿瘤", "T3N2M0"),
    ("C18.901", "结肠恶性肿瘤", "T4N1M1"),
    ("C22.001", "肝细胞癌", "T2N0M0")
]

HOSPITAL_INFO = [
    ("H1001", "北京协和医院", "P01", "东院"),
    ("H1002", "上海瑞金医院", "P02", "总院"),
    ("H1003", "广州中山医院", "P03", "肿瘤分院")
]

VITAL_SIGNS_RANGES = {
    'temperature': (36.0, 38.5),  # 体温(℃)
    'pulse': (50, 120),  # 心率
    'respiratory': (12, 24),  # 呼吸
    'bp_systolic': (90, 160),  # 收缩压
    'bp_diastolic': (60, 100)  # 舒张压
}


# ====== 时间范围配置 ======
def generate_day_range(start, end):
    start_date = datetime.strptime(start, "%Y-%m-%d")
    end_date = datetime.strptime(end, "%Y-%m-%d")
    return [
        (start_date + timedelta(days=i)).strftime("%Y-%m-%d")
        for i in range((end_date - start_date).days + 1)
    ]


DAY_RANGE = generate_day_range("2025-08-01", "2025-08-03")


# ====== 核心生成函数 ======
def generate_encrypted_records():
    sql_statements = []
    record_count = 0

    # 初始化计数器
    counters = {
        'patient_id': 3001,
        'visit_sn': 4001,
        'record_sn': 5001,
        'inpatient_no': 600001
    }

    for day in DAY_RANGE:
        records_per_day = 8 if datetime.strptime(day, "%Y-%m-%d").day % 2 == 0 else 5

        for _ in range(records_per_day):
            # 患者基础信息
            patient_id = f"PT{counters['patient_id']}"
            visit_sn = f"VIS{counters['visit_sn']}"
            record_sn = f"ENC_REC{counters['record_sn']}"

            counters['patient_id'] += 1
            counters['visit_sn'] += 1
            counters['record_sn'] += 1

            # 医院信息
            hospital_code, hospital_name, branch_code, branch_name = random.choice(HOSPITAL_INFO)

            # 生成加密数据
            chief_complaint = f"发现{random.choice(['肺部', '乳腺', '胃部'])}肿物{random.randint(1, 12)}个月"
            current_history = f"患者{random.randint(1, 24)}个月前发现症状，伴{random.choice(['疼痛', '消瘦', '咳嗽'])}"
            physical_exam = f"体温{random.uniform(*VITAL_SIGNS_RANGES['temperature']):.1f}℃，{random.choice(['可触及肿块', '淋巴结肿大'])}"

            # 选择肿瘤诊断
            diag_code, diag_name, tnm = random.choice(CANCER_DIAGNOSES)

            # 构建记录数据（包含明文和加密数据）
            data = {
                # 明文字段
                'hospital_code': hospital_code,
                'hospital_name': hospital_name,
                'inpatient_no': f"IP{counters['inpatient_no']}",
                'medical_record_no': f"MR{random.randint(100000, 999999)}",
                'patient_id': patient_id,
                'record_sn': record_sn,
                'record_status': 1,
                'visit_sn': visit_sn,
                'yy_collection_datetime': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'yy_upload_status': 0,
                'yy_etl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),

                # 需要加密的敏感字段（模拟加密）
                'auxiliary_exam': mock_encrypt(f"CT显示{diag_name}可能"),
                'chief_complaint': mock_encrypt(chief_complaint),
                'current_medhistory': mock_encrypt(current_history),
                'family_history': mock_encrypt(f"家族中{random.choice(['有', '无'])}肿瘤病史"),
                'physical_exam': mock_encrypt(physical_exam),
                'record_text': mock_encrypt(f"<病历>{chief_complaint}</病历>"),

                # 其他字段
                'body_surface_area': f"{random.uniform(1.5, 2.2):.2f}",
                'body_temperature': f"{random.uniform(*VITAL_SIGNS_RANGES['temperature']):.1f}",
                'confirmed_diagnosis': diag_name,
                'content_type': "ENCRYPTED_XML",
                'diastolic_pressure': str(random.randint(*VITAL_SIGNS_RANGES['bp_diastolic'])),
                'ecog_score': str(random.randint(0, 4)),
                'heart_rate': str(random.randint(*VITAL_SIGNS_RANGES['pulse'])),
                'height': str(random.randint(150, 185)),
                'hospitalization_times': str(random.randint(1, 3)),
                'kps_score': str(random.choice(["90", "80", "70", "60"])),
                'marriage_birth_history': mock_encrypt(f"已婚，育有{random.randint(0, 2)}子"),
                'menstrual_history': mock_encrypt(random.choice(["月经规律", "已绝经"])),
                'other_diagnosis': random.choice(["高血压", "糖尿病", ""]),
                'past_medhistory': mock_encrypt(random.choice(["既往体健", "有手术史"])),
                'patient_id_old': f"OLD_{patient_id}",
                'personal_medhistory': mock_encrypt(random.choice(["吸烟史", "饮酒史", "无"])),
                'primary_diagnosis': diag_name,
                'record_datetime': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'record_template_name': "加密肿瘤病历模板",
                'record_title': f"{diag_name}加密病历",
                'record_update_datetime': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'respiratory_rate': str(random.randint(*VITAL_SIGNS_RANGES['respiratory'])),
                'revision_diagnosis': None,
                'signature_doctor': mock_encrypt(fake.name()),
                'special_exam': mock_encrypt(f"{random.choice(['乳腺肿块', '肺部结节'])}检查阳性"),
                'systolic_pressure': str(random.randint(*VITAL_SIGNS_RANGES['bp_systolic'])),
                'weight': str(random.randint(40, 90)),
                'from_table': 'EMR_ENCRYPTED',
                'from_yy_record_id': f"ENC_{random.randint(10000, 99999)}",
                'yy_record_md5': hashlib.md5(record_sn.encode()).hexdigest(),
                'yy_upload_time': None,
                'yy_batch_time': day,
                'yy_record_batch_id': f"ENC_BATCH{day}_{record_sn}",
                'yy_backfill_time': None,
                'yy_backfill_status': None,
                'branch_code': branch_code,
                'branch_name': branch_name,
                'date_for_partition': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }

            counters['inpatient_no'] += 1
            record_count += 1

            sql = _generate_sql('b05_1_encode', data)
            sql_statements.append(sql)

    return sql_statements


def _generate_sql(table, data):
    columns = ', '.join([f'`{k}`' for k in data.keys()])
    values = []
    for v in data.values():
        if v is None:
            values.append('NULL')
        elif isinstance(v, (int, float)):
            values.append(str(v))
        else:
            escaped_value = str(v).replace("'", "''")
            values.append(f"'{escaped_value}'")
    return f"INSERT INTO `{table}` ({columns}) VALUES ({', '.join(values)});"


# ====== 执行生成 ======
if __name__ == "__main__":
    records = generate_encrypted_records()

    # 写入数据库
    MysqlUtils_AI.insert_data_to_hub(records, 'b05_1_encode')

    # 或写入SQL文件
    # FileUtil.generate_sql_file(records, "b05_1_encode_records.sql")
    print(f"已生成 {len(records)} 条加密入院记录")